package com.ryder.petmatediarybackend.common.util;

import com.ryder.petmatediarybackend.common.enums.DeviceTypeEnum;
import com.ryder.petmatediarybackend.module.log.entity.SysLoginLog;
import eu.bitwalker.useragentutils.UserAgent;
import jakarta.servlet.http.HttpServletRequest;

import java.time.LocalDateTime;

/**
 * 描述: 登录日志工具类
 *
 * <p>用于在登录或登录失败时构建统一的日志记录对象，便于插入数据库或写入消息队列。
 *
 * @author Ryder
 * @version 1.1
 * @since 1.0
 * 更新日期: 2025/10/25
 */
public class LoginLogUtil {

    /**
     * 构建登录日志记录
     *
     * @param userId       用户ID，可为空
     * @param deviceType   设备类型（WEB / APP）
     * @param loginStatus  登录状态（1=成功, 0=失败）
     * @param failReason   登录失败原因，可为空
     * @param request      HttpServletRequest
     * @param loginMethod  登录方式（1=账号密码 2=邮箱 3=SSO）
     * @param loginSource  登录来源（1=系统 2=微信 3=GitHub 4=QQ）
     * @param userAgentStr 浏览器 UA 信息，可为空
     * @return SysLoginLog 登录日志实体
     */
    public static SysLoginLog buildLoginLog(Long userId,
                                            DeviceTypeEnum deviceType,
                                            Integer loginStatus,
                                            String failReason,
                                            HttpServletRequest request,
                                            Integer loginMethod,
                                            Integer loginSource,
                                            String userAgentStr) {

        SysLoginLog log = new SysLoginLog();

        log.setUserId(userId);
        log.setLoginIp(IpUtil.getClientIp(request));
        log.setLoginLocation(IpUtil.getCityInfo(log.getLoginIp()));
        log.setLoginStatus(loginStatus);
        log.setLoginMethod(loginMethod);
        log.setLoginSource(loginSource);
        log.setFailReason(failReason);
        log.setLoginTime(LocalDateTime.now());

        log.setLoginDevice(parseDeviceInfo(deviceType, userAgentStr));

        return log;
    }

    /**
     * 构建设备/浏览器信息描述
     *
     * @param deviceType   设备类型（如 PC、APP）
     * @param userAgentStr 浏览器 UA 信息
     * @return 设备描述字符串，例如 “PC - Chrome (Windows 10)”
     */
    private static String parseDeviceInfo(DeviceTypeEnum deviceType, String userAgentStr) {
        if (userAgentStr == null || userAgentStr.isEmpty()) {
            return deviceType.getValue();
        }
        try {
            UserAgent ua = UserAgent.parseUserAgentString(userAgentStr);
            String os = ua.getOperatingSystem() != null ? ua.getOperatingSystem().getName() : "Unknown OS";
            String browser = ua.getBrowser() != null ? ua.getBrowser().getName() : "Unknown Browser";
            return String.format("%s - %s (%s)", deviceType.getValue(), browser, os);
        } catch (Exception e) {
            return deviceType.getValue() + " - Unknown Device";
        }
    }
}